package org.xiaojl.common.controller;

import java.util.ArrayList;
import java.util.List;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import org.xiaojl.common.Constants;
import org.xiaojl.common.SessionUser;
import org.xiaojl.common.base.BaseController;
import org.xiaojl.config.shiro.captcha.DreamCaptcha;
import org.xiaojl.modules.sys.entity.SysModule;
import org.xiaojl.modules.sys.entity.SysResource;
import org.xiaojl.modules.sys.service.SysModuleService;
import org.xiaojl.modules.sys.service.SysResourceService;
import org.xiaojl.modules.sys.service.SysUserRoleService;
import org.xiaojl.utils.ToolUtil;
import org.xiaojl.utils.WebUtil;

import com.baomidou.mybatisplus.mapper.EntityWrapper;

@Controller
public class LoginController extends BaseController{
	private static final Logger log = LoggerFactory.getLogger(LoginController.class);
//	@Autowired
//	private SysUserService sysUserService;
	@Autowired
	private SysUserRoleService sysUserRoleService;
	@Autowired
	private SysResourceService sysResourceService;
	@Autowired
    private DreamCaptcha dreamCaptcha;
	@Autowired
	private SysModuleService sysModuleService;
	
	@RequestMapping(value="/loginPage")
	public ModelAndView loginPage(Model model){
		try {
			log.info("进入登录页面！");
			if (SecurityUtils.getSubject().isAuthenticated()) {
				log.info("已经登录了，直接进入后台首页！");
			    return operatePage("redirect:/index",model);
			}
			model.addAttribute("message", "");
			model.addAttribute("captchaOpen", Constants.CAPTCHA_OPEN);
			
			return operatePage("login",model);
		} catch (Exception e) {
			log.error("进入登录页面出现异常:", e);
			return operateError("进入登录页面出现异常");
		}
	}
	
	@RequestMapping(value="/login")
	public ModelAndView login(String username,String password, String captcha, Model model){
		log.info("执行登录:username="+username+"，password="+password );
		String message = "";
		if (ToolUtil.isEmpty(username)) {
			message = "用户名不能为空" ;
			model.addAttribute("message", message);
			model.addAttribute("captchaOpen", Constants.CAPTCHA_OPEN);
			return operatePage("login",model);
        }
        if (ToolUtil.isEmpty(password)) {
        	message = "密码不能为空" ;
        	model.addAttribute("message", message);
        	model.addAttribute("captchaOpen", Constants.CAPTCHA_OPEN);
        	return operatePage("login",model);
        }
        if(Constants.CAPTCHA_OPEN){//判断是否开启了登录验证码功能
        	if (ToolUtil.isEmpty(captcha)) {
            	model.addAttribute("message", "验证码不能为空");
            	model.addAttribute("captchaOpen", Constants.CAPTCHA_OPEN);
            	return operatePage("login",model);
            }else{
            	if (!dreamCaptcha.validate(request, response, captcha)) {
            		model.addAttribute("message", "验证码不正确");
                	model.addAttribute("captchaOpen", Constants.CAPTCHA_OPEN);
                	return operatePage("login",model);
                }
            }
        }
        
        /** shiro 登录*/
        Subject user = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        // 设置记住密码
//	        token.setRememberMe(1 == rememberMe);
        try {
            user.login(token);
            log.info("执行登录验证成功！");
            return operatePage("redirect:/index",model);
            
        } catch (UnknownAccountException e) {
        	log.error("登录账号不存在！");
        	model.addAttribute("message", "用户名或者密码错误");
        } catch (DisabledAccountException e) {
        	log.error("登录账号被禁用了！");
            model.addAttribute("message", "账号未启用");
        } catch (IncorrectCredentialsException e) {
        	log.error("登录密码错误！");
        	model.addAttribute("message", "用户名或者密码错误");
        } catch (Throwable e) {
        	log.error("登录验证出现异常：",e);
            model.addAttribute("message", e.getMessage());
        }
        
        model.addAttribute("captchaOpen", Constants.CAPTCHA_OPEN);
        return operatePage("login",model);
	}
	
	/*@RequestMapping(value="/login")
	public String login(String username,String password,Model model){
		log.info("执行登录:username="+username+"，password="+password );
		String message = "";
		if (ToolUtil.isEmpty(username)) {
			message = "用户名不能为空" ;
			model.addAttribute("message", message);
			return "login";
        }
        if (ToolUtil.isEmpty(password)) {
        	message = "密码不能为空" ;
        	model.addAttribute("message", message);
        	return "login";
        }
        
        SysUser sysUser = sysUserService.selectOne(new EntityWrapper<SysUser>().eq("loginName", username));
        if(sysUser==null){
        	model.addAttribute("message", "用户名或者密码错误");
			return "login";
        }
        if(!password.equals(sysUser.getLoginPwd())){
        	model.addAttribute("message", "用户名或者密码错误");
			return "login";
        }
        String ip = WebUtil.getIpAddress(request);
        SessionUser suser = new SessionUser();
        suser.setLoginName(username);
        suser.setRealName(sysUser.getRealName());
        suser.setSysUser(sysUser);
        suser.setIp(ip);
        WebUtil.setSessionUser(request, suser);
        return REDIRECT+"index";
	}*/
	
	@RequestMapping(value="/logout")
	public ModelAndView logout(Model model){
		log.info("退出系统!");
		try {
			session.removeAttribute(Constants.SESSION_USER);
			
			Subject subject = SecurityUtils.getSubject();
			subject.logout();
		} catch (Exception e) {
			log.error("退出系统出现异常：",e);
		}
	        
		model.addAttribute("message", "");
		return operatePage("login",model);
	}
	
	@RequestMapping(value="/settingUI")
	public ModelAndView settingUI(Model model){
		
		return operatePage("settingUI",model);
	}
	
	@RequestMapping(value="/index")
	public ModelAndView index(Model model){
		log.info("进入系统首页");
		try {
			SessionUser user = WebUtil.getSessionUser(request);
			model.addAttribute("user", user);

			// 根据用户ID得到该用户的所有角色拼成的字符串
			String roleIds = sysUserRoleService.selectRoleIdsByUserId(user.getSysUser().getId());
			if (ToolUtil.isEmpty(roleIds)) {
				log.error("==>用户[" + user.getLoginName() + "]没有配置对应的权限角色");
				throw new RuntimeException("该帐号还未分配任何系统权限");
			}
			//查询当前用户具有的模块
			List<SysModule> list = sysModuleService.selectListByRoleId(roleIds);
			model.addAttribute("oneMenuList", list);
			
			//拿到list的第一条记录，获取它对应的菜单
			if(list!=null && list.size()>0){
				SysModule sr = list.get(0);
				String tree = this.buildMenuTree(user,sr.getId());
				model.addAttribute("tree", tree);
			}
			
			return operatePage("index_hxdhl",model);
		} catch (Exception e) {
			log.error("进入系统首页异常:",e);
			model.addAttribute("message", e.getMessage());
			return operatePage("login",model);
		}
	}
	
	@RequestMapping(value="/getMenuTree")
	public ModelAndView getMenuTree(Model model, Long pid){
		log.info("获取系统设置模块菜单");
		try {
			List<SysResource> list = sysResourceService.selectList(new EntityWrapper<SysResource>().eq("pid",pid));
			if(ToolUtil.isEmpty(list)){
				return operateError("父ID【"+pid+"】下没有子菜单！");
			}
			
			SessionUser user = WebUtil.getSessionUser(request);
			model.addAttribute("user", user);

			String tree = this.buildMenuTree(user,pid);
			model.addAttribute("tree", tree);
			log.info("tree:"+tree);
			return operatePage("indexMenu",model);
		} catch (Exception e) {
			log.error("获取系统设置模块菜单异常:",e);
			return operateError("获取系统设置模块菜单失败");
		}
	}
	
	
	/**
	 * 获取用户的菜单权限
	 */
	private String buildMenuTree(SessionUser user,Long pid) throws Exception {
		// 根据用户ID得到该用户的所有角色拼成的字符串
		String roleIds = sysUserRoleService.selectRoleIdsByUserId(user.getSysUser().getId());
		if (ToolUtil.isEmpty(roleIds)) {
			log.error("==>用户[" + user.getLoginName() + "]没有配置对应的权限角色");
			throw new RuntimeException("该帐号还未分配任何系统权限");
		}
		// 根据操作员拥有的角色ID,构建管理后台的树形权限功能菜单
		return this.buildTreeByRoleIds(roleIds,pid);
	}
	
	/**
	 * 根据操作员拥有的角色ID,构建管理后台的树形权限功能菜单
	 */
	private String buildTreeByRoleIds(String roleIds,Long pid) throws Exception {
		List<SysResource> treeData = null;
		try {
			treeData = sysResourceService.selectListByRoleIds(roleIds,"0");
			if (ToolUtil.isEmpty(treeData)) {
				throw new RuntimeException("该用户没有分配菜单权限"); // 该用户没有分配菜单权限
			}
		} catch (Exception e) {
			log.error("根据角色查询菜单出现异常！", e);
			throw new RuntimeException("根据角色查询菜单出现错误"); // 查询当前角色的
		}
		StringBuffer strJson = new StringBuffer();
		buildTreeByResource(pid+"", strJson, treeData);
		return strJson.toString();
	}

	/**
	 * 构建管理后台的树形权限功能菜单
	 * 
	 * @param pId
	 * @param treeBuf
	 * @param menuList
	 */
	private void buildTreeByResource(String pId, StringBuffer treeBuf,List<SysResource> menuList) {
		List<SysResource> listMap = getSonMenuListByPid(pId.toString(), menuList);
		for (SysResource res : listMap) {
			String id = res.getId()+"";// id
			String name = res.getName();// 名称
			String isLeaf = res.getIsLeaf()+"";// 是否叶子
			String level = res.getLevel()+"";// 菜单层级（1、2、3、4）
			int type = res.getType();
			String url = res.getUrl(); // ACTION访问地址
			String navTabId = "";
			if (!ToolUtil.isEmpty(res.getTargetName())) {
				navTabId = res.getTargetName(); // 用于刷新查询页面
			}
			if ("1".equals(level)) {
				treeBuf.append("<div class='accordionHeader'>");
				treeBuf.append("<h2> <span>Folder</span> " + name + "</h2>");
				treeBuf.append("</div>");
				treeBuf.append("<div class='accordionContent'>");
			}
			//是叶子吗：0-是，1-不是
			/**
			 * 如果type=0（菜单），则isLeaf=0 表示叶子，isLeaf=1 表示具有子菜单，isLeaf=2 表示具有子按钮 ；
			 * 如果type=1（按钮），则isLeaf=0
			 */
			if(type==0){
				if("0".equals(isLeaf) || "2".equals(isLeaf)){//没有了子菜单，可能具有子按钮
					treeBuf.append("<li><a href='" + url + "' target='navTab' rel='" + navTabId + "'>" + name + "</a></li>");
				}else if("1".equals(isLeaf)){//还具有子菜单
					if ("1".equals(level)) {
						treeBuf.append("<ul class='tree treeFolder'>");
					} else {
						treeBuf.append("<li><a>" + name + "</a>");
						treeBuf.append("<ul>");
					}
					//递归调用
					buildTreeByResource(id, treeBuf, menuList);
					if ("1".equals(level)) {
						treeBuf.append("</ul>");
					} else {
						treeBuf.append("</ul></li>");
					}
				}else{
					log.info("资源数据异常："+res.getName()+",id="+res.getId());
				}
			}
			if ("1".equals(level)) {
				treeBuf.append("</div>");
			}
		}
	}

	/**
	 * 根据(pId)获取(menuList)中的所有子菜单集合.
	 * 
	 * @param pId
	 *            父菜单ID.
	 * @param menuList
	 *            菜单集合.
	 * @return sonMenuList.
	 */
	private List<SysResource> getSonMenuListByPid(String pId,
			List<SysResource> menuList) {
		List<SysResource> sonMenuList = new ArrayList<SysResource>();
		for (SysResource menu : menuList) {
			if (menu != null) {
				String parentId = menu.getPid()+"";// 父id
				if (parentId.equals(pId)) {
					sonMenuList.add(menu);
				}
			}
		}
		return sonMenuList;
	}
}
